package xmlexporter;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

import entry.Entry;

public class XmlExporterTest {

	private static final String THREE_ENTRIES_CORRECT_FILE_XML = "threeEntriesCorrectFile.xml";
	private static final String ONE_ENTRY_CORRECT_FILE_XML = "oneEntryCorrectFile.xml";
	private static final String EMPTY_CORRECT_FILE_XML = "emptyCorrectFile.xml";
	private static final String TESTFILE2_XML = "testfile2.xml";
	private static final String TESTFILE1_XML = "testfile1.xml";
	private static final String THREE_ITEMS_TARGET_XML = "threeItemsTarget.xml";
	private static final String ONE_ITEM_TARGET_XML = "oneItemTarget.xml";
	private static final String EMPTY_TARGET_XML = "emptyTarget.xml";
	private static final String FILENAME_PREFIX = "src\\xmlexporter\\testfiles\\";
	
	private XmlExporter xmlExporter;
	private int numberOfEntry = 1;

	@Before
	public void setUp() {
		xmlExporter = new XmlExporter();
		deleteFileIfExists(EMPTY_TARGET_XML);
		deleteFileIfExists(ONE_ITEM_TARGET_XML);
		deleteFileIfExists(THREE_ITEMS_TARGET_XML);
	}

	private void deleteFileIfExists(String name) {
		File emptyTarget = createFile(name);
		if (emptyTarget.exists()) {
			emptyTarget.delete();
		}
	}

	@Test
	public void internalTest_compareFilesTest() throws IOException {
		File file = createFile(TESTFILE1_XML);
		File theSameFile = createFile(TESTFILE2_XML);
		assertTrue(areFilesTheSame(file, theSameFile));
	}

	@Test
	public void internalTest_compareFilesTestFail() throws IOException {
		File file = createFile(TESTFILE2_XML);
		File anotherFile = createFile(EMPTY_CORRECT_FILE_XML);
		assertFalse(areFilesTheSame(file, anotherFile));
	}

	@Test
	public void exportEmpty() throws IOException {
		File correctFile = createFile(EMPTY_CORRECT_FILE_XML);
		File target = createFile(EMPTY_TARGET_XML);
		List<Entry> list = createListOfEntries(0);

		xmlExporter.export(list, target);

		assertTrue(areFilesTheSame(correctFile, target));
	}

	@Test
	public void exportOneItemList() throws IOException {
		File correctFile = createFile(ONE_ENTRY_CORRECT_FILE_XML);
		File target = createFile(ONE_ITEM_TARGET_XML);
		List<Entry> list = createListOfEntries(1);

		xmlExporter.export(list, target);

		assertTrue(areFilesTheSame(correctFile, target));
	}

	@Test
	public void exportTreeItemsList() throws IOException {
		File correctFile = createFile(THREE_ENTRIES_CORRECT_FILE_XML);
		File target = createFile(THREE_ITEMS_TARGET_XML);
		List<Entry> list = createListOfEntries(3);

		xmlExporter.export(list, target);

		assertTrue(areFilesTheSame(correctFile, target));
	}

	private File createFile(String name) {
		File newFile = new File(FILENAME_PREFIX + name);
		return newFile;
	}

	private List<Entry> createListOfEntries(int numberOfEntries) {
		List<Entry> list = new ArrayList<Entry>();
		for (int i = 0; i < numberOfEntries; i++) {
			list.add(createExampleEntry());
		}
		return list;
	}

	private Entry createExampleEntry() {
		Entry e = new Entry();
		e.setAbbr("ABBR " + numberOfEntry);
		e.setExtension("Abbreviation " + numberOfEntry);
		e.setDescription("sample description " + numberOfEntry);
		numberOfEntry++;
		return e;
	}

	private boolean areFilesTheSame(File correctFile, File targetFile) throws IOException {
		// System.out.println("comparison: " + correctFile.getName() + " " +
		// targetFile.getName());
		BufferedReader correctFileReader = new BufferedReader(new FileReader(
				correctFile));
		BufferedReader targetFileReader = new BufferedReader(new FileReader(
				targetFile));
		return compareReaders(correctFileReader, targetFileReader);
	}

	private boolean compareReaders(BufferedReader correct, BufferedReader target)
			throws IOException {
		String[] pair;
		while ((pair = readPairOfLines(correct, target)) != null) {
			// System.out.println("pair: " + pair[0] + " " + pair[1]);
			if (pair[0] == null || !pair[0].equalsIgnoreCase(pair[1])) {
				return false;
			}
		}
		return true;
	}

	private String[] readPairOfLines(BufferedReader correct,
			BufferedReader target) throws IOException {
		String correctLine = correct.readLine();
		String targetLine = target.readLine();
		if (correctLine == null && targetLine == null) {
			return null;
		}
		String[] pair = new String[] { correctLine, targetLine };
		return pair;
	}

}
